// Raf Lempens & Bjorn Schobben
#include "DropBehavior.h"
#include "DropAbilityVisitor.h"
#include "ActivateAbilityVisitor.h"
#include "ActivateStep.h"

DropBehavior::DropBehavior(): activatableObject(0), activatableInterface(0)
{
}

DropBehavior::~DropBehavior()
{
	Clear();
}

void DropBehavior::Clear()
{
	std::list<GameStep*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		delete (*it);
	}

	steps.clear();
}

void DropBehavior::SetActivator(GameObject* pitfall)
{
	ActivateAbilityVisitor activateVisitor;

	pitfall->Accept(activateVisitor);

	if (activateVisitor.FoundAbility())
	{
		activatableObject = pitfall;
		activatableInterface = activateVisitor.ActivatableInterface();
	}
}



void DropBehavior::GenerateSteps(Board& board)
{
	Clear();

	if (!activatableObject && !activatableInterface)
		return;

	Cell& cell = board.CellAt(activatableObject);

	const std::list<GameObject*>& cellobjects = cell.GetObjects();
	std::list<GameObject*>::const_iterator it;

	
	for(it = cellobjects.begin(); it != cellobjects.end(); ++it)
	{
		GameObject* object = (*it);

		DropAbilityVisitor dropVisitor;

		object->Accept(dropVisitor);

		if (dropVisitor.FoundAbility())
		{
			AddStep(object, dropVisitor.DroppableInterface());
		}
	}

	if (steps.size())
	{
		ActivateStep* step = new ActivateStep();

		step->SetObject(activatableObject, activatableInterface);
		steps.push_front(step);
	}
}

void DropBehavior::AddStep(GameObject* object, Droppable* droppable)
{
	DropStep* step = new DropStep();

	step->SetObject(object, droppable);

	steps.push_back(step);
}


void DropBehavior::Execute()
{
	std::list<GameStep*>::iterator it;

	for(it = steps.begin(); it != steps.end(); ++it)
	{
		(*it)->Execute();
	}
}


